iT邦幫忙

2021 iThome 鐵人賽

DAY 16
1

本來前端應該要更早點講的,不過 Flask 的前端有了傳入的值的話,可以有更多的操作,所以就放到這邊才講了。

Flask 的前端是由 Jinja2 樣版引擎來處理,而樣板引擎可以像是程式語言一樣對參數進行各種處裡。

後端

首先,前端的頁面預設是放在專案根目錄下的 templates (有 s,可以改位置,但下一篇靜態檔案時再說),就像這樣:

ithome/
├── templates
│   └── index.html
├── app.py
├── configs.py
├── Pipfile
└── Pipfile.lock

既然這篇主題是前端,那麼先把跟主題無關的後端部分快速講完。後端要傳回頁面是使用 render_template() 這個 function,這個 function 第一個參數必須是一個頁面的檔案;後面跟著要傳入頁面的參數,使用 key-value 傳入,value 可以是 dict 、 list 或一般的變數。就像這樣:

app.py

@app.route('/')
def index():
    return render_template('index.html')
    # or
    return render_template('index.html', username='<username>')
    # or
    return render_template('index.html', username=['A', 'B', 'C'])
    # or
    return render_template('index.html', username={'Users': ['A', 'B', 'C'])

後端要傳回頁面大概可以用這幾種方式,不一定只能有一個 key-value ,也可以有多個(中間皆使用逗點分開)。

前端

接著就要來說道前端頁面的部份了,剛剛講到樣板引擎可以像程式語言一樣對參數進行處理,甚至進行各種條件判斷。說到這些,想當然的一定有 if-else 跟 for 了吧。

Jinja2 樣板引擎可以處裡 .html 檔(雖然可以處裡的不只 .html 就是了),在 Jinja2 除了可以解析普通的 HTML 語法,還有兩種特殊的標籤:{{ }}{% %}{{ }} 是使用在渲染到頁面上的標籤;{% %} 是使用在各種判斷以及迴圈使用的標籤。需要注意的大概就這樣而已,接著實際操作一次會更加清晰。

if-elif-else

第一個是最常用的 if-elif-else,實際來看一下前後端如何實作吧:

app.py

@app.route('/')
def index():
    return render_template('index.html')

@app.route('/<username>')
def user_home(username):
    return render_template('index.html', username=escape(username))

index.html

<!DOCTYPE html>
<html>

<head>
    <meta charset="UTF-8" />
    <title>template value</title>
</head>

<body>
    <div>
        {% if username %}
            <h1>Welcome {{ username }}</h1>
        {% else %}
            <h1>Hello</h1>
        {% endif %}
    </div>
</body>

</html>

這樣就可以再有輸入使用者名稱的時候,會自動顯示出不同的頁面。像這樣:

http://localhost:5000/

http://localhost:5000/User

for

第二個也是很常使用的 for,這邊也直接來看如何實作吧:

app.py

@app.route('/')
def index():
    return render_template('index.html')

@app.route('/<username>')
def user_home(username):
    return render_template('index.html', username=escape(username))


@app.route('/<int:time>')
def user_list_home(time):  # 真的不知道要取什麼名字了
    users = []
    for i in range(time):
        users.append("user" + str(i))

    return render_template('index.html', users=users)

index.html

<!DOCTYPE html>
<html>

<head>
    <meta charset="UTF-8" />
    <title>template value</title>
</head>

<body>
    <div>
        {% if username %}
            <h1>Welcome {{ username }}</h1>
        {% elif users %}
            {% for username in users %}
                <h1>Welcome {{ username }}</h1>
            {% endfor %}
        {% else %}
            <h1>Hello</h1>
        {% endif %}
    </div>
</body>

</html>

基本上只是根據前一個小改而已,所以輸入前面那兩個 URL 也會出現一樣的結果,不一樣的只有這個:

http://localhost:5000/5

常用的邏輯控制大概就這樣,接著要講不太一樣的東西。

extends & block

如果現在要做多個畫面,四周都差不多,只有中間內容不太一樣(就像這篇跟上一篇一樣,只有中間內容不一樣),這時有兩個方法可以解決。第一個想到的就是萬能的 ctrl + c & ctrl + v 對吧,真的很好用我知道,但是有點太慢了。第二個就是這個 extendsblock

那這個要怎麼用呢?讓我們先打架構改成這樣,再根據上面的程式小改一下。

ithome
├── templates
│   ├── res  # 先隨便取個名字,不用做資料夾也行。
│   │   └── home.html  # 它跟 base.html 同一層也可以
│   ├── base.html
│   └── index.html
├── app.py
├── configs.py
├── Pipfile
└── Pipfile.lock

app.py

@app.route('/')
def index():
    return render_template('index.html')

@app.route('/<username>')
def user_home(username):
    return render_template('res/home.html', username=escape(username))


@app.route('/<int:time>')
def user_list_home(time):  # 真的不知道要取什麼名字了
    users = []
    for i in range(time):
        users.append("user" + str(i))

    return render_template('res/home.html', users=users)

base.html

<!DOCTYPE html>
<html>

<head>
    <meta charset="UTF-8" />
    <title>{% block title %}{% endblock %}</title>
</head>

<body>
    <div>
        {% block content %}
        {% endblock %}
    </div>
</body>

</html>

index.html

{% extends 'base.html' %}

{% block title %}
    Index
{% endblock %}

{% block content %}
    <h1>Hello</h1>
{% endblock %}

home.html

{% extends 'base.html' %}

{% block title %}
    Home
{% endblock %}

{% block content %}
    {% if username %}
        <h1>Welcome {{ username }}</h1>
    {% elif users %}
        {% for username in users %}
            <h1>Welcome {{ username }}</h1>
        {% endfor %}
    {% else %}
        <a href={{ url_for('index') }}><button>Index</button></a>
    {% endif %}
{% endblock %}

改好之後,輸入上面的三個 URL 的話,應該會得到一樣的結果(廢話,因為只是把它們拆開而已)。

看到這裡,也大概知道它是如何運作的了吧!就是同樣的東西共享,在需要填入不同東西的地方挖個洞、取個名字(名子隨便取,但是盡量取有意義的名字),然後在子頁面繼承之後,輸入名字與要填入的東西,就可以達成這樣的效果。

那麼就大概這樣,這邊只有 HTML 相關的東西,有關 CSS 與 JavaScript 的東西,以及想要改位置的方式下一篇會講到。

大家掰~掰~


上一篇
Day 15 Flask 回傳參數
下一篇
Day 17 Flask 靜態文件
系列文
月光下的Flask之旅30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言